1. Field of the Invention
The invention generally relates to software used to interface with hardware and more specifically relates to software for use in low-level input/output operations.
2. Description of the Related Art
Classically, a computer or other computing device had a single processor and a relatively fixed set of additional devices such as peripheral components. When the computer started operation, the processor utilized a BIOS (Basic Input Output System) to communicate with the rest of the system until more sophisticated software such as an operating system could be started. As operation of the computer proceeded, the operating system would still need to communicate with the rest of the computer, and might use the input/output (I/O) code available in the BIOS for this communication, along with drivers included in the operating system for this purpose. Alternatively, the operating system would use its own code, possibly including drivers, which might read addresses for I/O from the BIOS but otherwise leave the BIOS undisturbed during normal operation. The BIOS code typically included some basic in (input) and out (output) instructions which the processor simply executed, and in some instances also included various setup and cleanup instructions which served to make I/O effective and coherent.
Much of this theory of operations depended on dedicated memory locations (addresses) that could be used to write to or read from registers associated with hardware other than the processor. Typically, these addresses could be set using hardware configuration devices such as jumpers or fuses, resulting in a few dedicated addresses at which the device or component in question could be accessed. In early IBM PC systems, the addresses in question typically were close to the zero address of the system, and in some systems were always in the zero to 4095 range (or 0–64K range for latter systems). Moreover, in some systems, the BIOS would have dedicated addresses associated with it, where certain routines within the BIOS could be found, or where the BIOS would look for certain data. Additionally, strong ordering of operations was the norm, if a first datum was written at a first address in a program, and then a second datum was written at a second address, there was no chance that the second datum would be written before the first datum was written. When the first datum was data to be written, and the second datum was an instruction to write the information to disk, this ordering was important.
With the advent of newer technology, this model is not as simple. Multiple processors are involved in some systems. Processors include pipelining with complicated models for conditional processing of branches, stalls due to delays in the system, and parallel execution of instructions. Caches introduce further complexity, allowing for data to be read and written at a first location without going beyond the cache to the device dedicated to storing data at the first location. Components may be inserted or removed from a system in real-time during normal operation. Virtual memory management may mean that the processor understands that a piece of data is being written at a first location but the surrounding I/O components redirect that data to a second location based on page tables and other translations of addresses. All of these changes to the computer mean that the basic input and output routines may be much more complicated to write and manage than they were in earlier days.
Recently, a new standard, known as the Extensible Firmware Interface (EFI), was introduced. As its name implies, EFI enables systems that employ the interface and associated architecture to extend the firmware operations of those systems beyond the basic services provided by the BIOS or original firmware that is provided with system. Under EFI, various system level events, such as I/O operations, are handled through drivers that are specifically tailored for such tasks. Typically, the EFI drivers are written to support particular CPU architectures. As a result, respective sets of drivers must be written for each processor architecture. In addition to processor-architecture considerations, the firmware drivers need to support both physical and virtual CPU execution modes, so that I/O operations can be performed in the pre-boot environment, the OS present environment, and in exception-handling code that may execute in virtual and physical execution modes.